package com.binguo.wxapi.controller;

import com.binguo.checker.CustomerChecker;
import com.binguo.checker.ShopChecker;
import com.binguo.common.enums.CardType;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.paymodel.WXResponse;
import com.binguo.helper.FaceHelperV3;
import com.binguo.model.api.vo.OrderVO;
import com.binguo.model.mapper.PayCardMapper;
import com.binguo.model.model.*;
import com.binguo.model.repository.CustomerExtendRepository;
import com.binguo.model.repository.CustomerRepository;
import com.binguo.model.repository.PayCardRepository;
import com.binguo.model.wxapi.vo.CardsVO;
import com.binguo.service.OrderService;
import com.binguo.wxapi.form.*;
import com.binguo.wxapi.result.Result;
import com.binguo.wxapi.result.ResultGenerator;
import com.binguo.wxapi.service.*;
import com.binguo.wxapi.wxpay.WXServerPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.binguo.common.exception.ErrorCode.UPLOAD_ERROR;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;


/**
 * Created by haibang on 18/5/7.
 */
@Api(tags = "小程序: 卡包")
@RestController
@RequestMapping
public class WXCardController {

    private static Logger logger = LoggerFactory.getLogger(WXCardController.class);

    private final String imgURL = "http://img.binguoai.com/";

    @Autowired
    WXCardService wxCardService;

    @Autowired
    ShopChecker shopChecker;

    @Autowired
    CustomerChecker customerChecker;

    @Autowired
    WXPayService wxPayService;

    @Autowired
    OrderService orderService;


    @Autowired
    WXLoginService wxLoginService;

    @Autowired
    PictureService pictureService;

    @Autowired
    CustomerRepository customerRepository;

    @Autowired
    CustomerExtendRepository customerExtendRepository;

    @Autowired
    WXServerPayService wxServerPayService;

    @Autowired
    PayCardRepository payCardRepository;

    @Resource
    PayCardMapper payCardMapper;




    @GetMapping(value = "/api/wxapp/paycard/banner", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "首页banner", notes = "")
    public Result list() {
//        List<BannerVO> vos = wxCardService.bannerList();
        return ResultGenerator.genSuccessResult();
    }


    @PostMapping(value = "/api/wxapp/person/update", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创人", notes = "通过CreateCardForm")
    public Result personcreate(@RequestParam String shopId, @RequestParam String faceUrl ,
                               @RequestParam Integer customerId) {
        String personId = shopId + "_" + customerId;
//        String faceUrl = "http://img.binguoai.com/Vincet.jpeg";

        //添加人脸
        String faceId = FaceHelperV3.addFace(personId, faceUrl) ;
        if (faceId == null) {
            throw new ServiceException(UPLOAD_ERROR);
        }

        return ResultGenerator.genSuccessResult();
    }



    @PostMapping(value = "/api/wxapp/person/create", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创人", notes = "通过CreateCardForm")
    public Result personcreate(@RequestParam String shopId, @RequestParam String faceUrl ,
                               @RequestParam String name, @RequestParam(required = false) String phone

            , @RequestParam(required = false) String cardId
                               ) {
        Condition condition = new Condition(Customer.class);

        condition.or().andEqualTo("phone", phone);


        List<Customer> customerList = customerRepository.findByCondition(condition);

        Customer customer = null;
        CustomerExtend customerExtend = null;
        if (customerList != null && customerList.size() > 0) {
            customer = customerList.get(0);

            Condition customerExtendCondition = new Condition(CustomerExtend.class);
            customerExtendCondition.or().andEqualTo("customerId", customer.getId())
                .andEqualTo("shopId", shopId)
            ;
            List<CustomerExtend> customerExtendList =
                    customerExtendRepository.findByCondition(customerExtendCondition);

            if (customerExtendList != null && customerExtendList.size() > 0) {
                customerExtend = customerExtendList.get(0);
            }
        }else {
            customer = new Customer();
            customer.setName(name);
            customer.setPhone(phone);
            customerRepository.save(customer);
        }

        if (customerExtend == null) {
            customerExtend = new CustomerExtend();
            customerExtend.setShopId(Integer.valueOf(shopId));
            customerExtend.setCustomerId(customer.getId());
            customerExtend.setUserStatus(1);
            customerExtend.setIsAudit(1);
            customerExtendRepository.save(customerExtend);
        }

        CreateCardForm createCardForm = new CreateCardForm();
        createCardForm.setShopId(Integer.valueOf(shopId));
        createCardForm.setCardType(1);
        createCardForm.setFaceUrl(faceUrl);
        createCardForm.setCustomerId(customer.getId());

        PayCard payCard = PayCard.builder()
                .shopid(Integer.valueOf(shopId))
                .customerid(customer.getId())
                .cardno(cardId)
                .cardtype(CardType.BINGUO_CARD.getCode().byteValue())
//                .cardtype(CardType.YKT_CARD.getCode().byteValue())
                .deleted(false)
                .name(name + "的一卡通")
                .wxAccountbalance(0l)
                .bzAccountbalance(1000l)
                .yktAccountbalance(0l)
                .ismaster(false)
                .isnopasswordpay(true)
                .build();

        payCard.setAccountbalance(0l);

        payCardRepository.save(payCard);

        PayCard temp = new PayCard();
        temp.setId(payCard.getId());
        temp.setCardno("" + payCard.getId());

        payCardMapper.updateByPrimaryKeySelective(temp);

        return this.create(createCardForm);


    }


    @PostMapping(value = "/api/wxapp/person/createYKT", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创一卡通", notes = "通过CreateCardForm")
    public Result createYKT(@RequestParam String shopId,
                            @RequestParam String name,
                            @RequestParam(required = false) String cardId) {
        Condition condition = new Condition(Customer.class);

        condition.or().andEqualTo("name", name);


        List<Customer> customerList = customerRepository.findByCondition(condition);

        Customer customer = null;
        CustomerExtend customerExtend = null;
        if (customerList != null && customerList.size() > 0) {
            customer = customerList.get(0);

            Condition customerExtendCondition = new Condition(CustomerExtend.class);
            customerExtendCondition.or().andEqualTo("customerId", customer.getId());
            List<CustomerExtend> customerExtendList =
                    customerExtendRepository.findByCondition(customerExtendCondition);

            if (customerExtendList != null && customerExtendList.size() > 0) {
                customerExtend = customerExtendList.get(0);
            }
        }else {
            customer = new Customer();
            customer.setName(name);
            customer.setPhone("19900020001");
            customerRepository.save(customer);
        }

        if (customerExtend == null) {
            customerExtend = new CustomerExtend();
            customerExtend.setShopId(Integer.valueOf(shopId));
            customerExtend.setUserStatus(1);
            customerExtend.setCustomerId(customer.getId());
            customerExtend.setIsAudit(1);
            customerExtendRepository.save(customerExtend);
        }

        PayCard payCard = PayCard.builder()
                .shopid(Integer.valueOf(shopId))
                .customerid(customer.getId())
                .cardno(cardId)
                .cardtype(CardType.YKT_CARD.getCode().byteValue())
                .deleted(false)
                .name(name + "的一卡通")
                .wxAccountbalance(0l)
                .bzAccountbalance(0l)
                .yktAccountbalance(0l)
                .ismaster(false)
                .isnopasswordpay(true)
                .build();

        payCard.setAccountbalance(0l);

        payCardRepository.save(payCard);

        return ResultGenerator.genSuccessResult();


    }

    @PostMapping(value = "/api/wxapp/paycard/create", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创建虚拟卡", notes = "通过CreateCardForm")
    public Result create(@RequestBody @Valid CreateCardForm form) {

        shopChecker.checkNotExist(form.getShopId());
        customerChecker.checkNotExist(form.getCustomerId());
        String cardId = wxCardService.createCard(form.getShopId(), form.getCustomerId(), form.getFaceUrl(), form.getCardType());
        return ResultGenerator.genSuccessResult(cardId);
    }

    @PostMapping(value = "/api/wxapp/paycard/createNew", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创建虚拟卡", notes = "通过CreateCardForm")
    public Result createNew(@RequestBody @Valid CreateCardNewForm form) {

        shopChecker.checkNotExist(form.getShopId());
        customerChecker.checkNotExist(form.getCustomerId());
        String cardId = wxCardService.createCardNew2(form.getShopId(), form.getCustomerId(), form.getCustomerName(),
                form.getUserGroupId());
        return ResultGenerator.genSuccessResult(cardId);
    }

    @PostMapping(value = "/api/wxapp/paycard/createCardByShop", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "商户传参创建虚拟卡", notes = "通过CreateCardForm")
    public Result createCardByShop(@RequestBody @Valid CreateCardByShopForm form) {

        shopChecker.checkNotExist(form.getShopId());
        Customer customer = wxLoginService.createCustomer(form.getShopId(),form.getShopCustomerId(),form.getShopCustomerName());
        String faceURL = imgURL+pictureService.getImgURL(form.getFaceUrl());
        String cardId =  wxCardService.createCard(form.getShopId(),customer.getId(),faceURL,1);
        return ResultGenerator.genSuccessResult(cardId);
    }

    @PostMapping(value = "/api/wxapp/paycard/YKT/create", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创建一卡通", notes = "通过CreateYKTCardForm")
    public Result createYKT(@RequestBody @Valid CreateYKTCardForm form) {

        shopChecker.checkNotExist(form.getShopId());
        customerChecker.checkNotExist(form.getCustomerId());

        wxCardService.createYKTCard(form.getShopId(), form.getCustomerId(), form.getCardNo(), form.getCardType());
        return ResultGenerator.genSuccessResult();
    }


    @PostMapping(value = "/api/wxapp/paycard/YKT/delele", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "删除一卡通", notes = "通过CancelCardForm")
    public Result deleleYKT(@RequestBody @Valid CancelCardForm form) {

        customerChecker.checkNotExist(form.getCustomerId());

        wxCardService.deleteYKTCard(form.getCustomerId(), form.getCardNo());
        return ResultGenerator.genSuccessResult();
    }


    @PostMapping(value = "/api/wxapp/paycard/update", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "修改卡", notes = "通过updateCardForm")
    public Result update(@RequestBody @Valid UpdateCardForm form) {
        customerChecker.checkNotExist(form.getCustomerId());
        wxCardService.updateCard(form);
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping(value = "/api/wxapp/paycard/list/{customerId}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "我的卡包", notes = "通过客户id")
    public Result list(@PathVariable Integer customerId) {
        customerChecker.checkNotExist(customerId);
        List<CardsVO> vos = wxCardService.list(customerId);
        return ResultGenerator.genSuccessResult(vos);
    }

    @GetMapping(value = "/api/wxapp/paycard/info/{cardId}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "我的卡包", notes = "通过客户id")
    public Result cardInfo(@PathVariable Integer cardId) {
        PayCard payCard = wxCardService.findByCardId(cardId);
        Shop shop = wxCardService.findShopById(payCard.getShopid());

        return ResultGenerator.genSuccessResult(shop.getCardimgurl());
    }

    @PostMapping(value = "/api/wxapp/paycard/recharge", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "虚拟卡充值", notes = "通过RechargeCardForm")
    public Result recharge(@RequestBody @Valid RechargeCardForm form,
                           HttpServletRequest request) {
        WXResponse wxResponse = wxCardService.rechargeChoise(form, getIpAddr(request));
        return ResultGenerator.genSuccessResult(wxResponse);
    }

    @PostMapping(value = "/api/wxapp/paycard/cancelcard", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "虚拟卡退卡", notes = "通过CancelCardForm")
    public Result cancelcard(@RequestBody @Valid CancelCardForm form) {
        wxCardService.cancelcard(form);
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping(value = "/api/wxapp/paycard/{cardId}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "交易统计:虚拟卡充值记录", notes = "通过cardId")
    public Result payCardOrderlist(@PathVariable Integer cardId) {
        List<OrderVO> vos = orderService.findPayCardOrder(cardId);
        return ResultGenerator.genSuccessResult(vos);
    }


    @GetMapping(value = "/api/wxapp/cardimg/{cardId}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取卡片二维码", notes = "通过cardId")
    public Result cardimg(@PathVariable Integer cardId) {
        String cardImg = wxCardService.getPayCode(cardId);
        return ResultGenerator.genSuccessResult(cardImg);
    }


    @GetMapping(value = "/api/wxapp/contractInfo/{cardId}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取签约相关参数", notes = "通过cardId")
    public Result contractInfo(@PathVariable Integer cardId) {
        Map<String, String> map = wxPayService.getContractInfo(cardId);
        return ResultGenerator.genSuccessResult(map);
    }


    @GetMapping(value = "/api/wxapp/deletecontract/{cardId}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "免密支付解约", notes = "通过cardId")
    public Result deletecontract(@PathVariable Integer cardId) throws Exception {
        Boolean isSuccess = wxCardService.deleteContract(cardId);
        Map<String, Boolean> map = new HashMap<>(1);
        map.put("isSuccess", isSuccess);
        return ResultGenerator.genSuccessResult(map);
    }



    @PostMapping(value = "/api/wxapp/refund/notity", produces = APPLICATION_XML_VALUE)
    public String refundNotity(HttpServletRequest request) {
        return wxPayService.reFundNotify(request);
    }



    @PostMapping(value = "/api/wxapp/notity", produces = APPLICATION_XML_VALUE)
    public String notity(HttpServletRequest request) {
        return wxPayService.notify(request);
    }



    @PostMapping(value = "/api/wxapp/serverpay/notity", produces = APPLICATION_XML_VALUE)
    public String serverpayNotity(HttpServletRequest request) {
        logger.info("notify");

        StringBuilder sb = new StringBuilder();
        try
        {
            BufferedReader ina = new BufferedReader(
                    new InputStreamReader(request.getInputStream()));
            String line = null;
            while ((line = ina.readLine()) != null)
            {
                sb.append(line);
            }
            logger.info("weixin server pay body:  " + sb  );

        }catch (Exception e){
            e.printStackTrace();
        }

        return wxServerPayService.notify(sb.toString());
    }



    @PostMapping(value = "/api/wxapp/contract/notity", produces = APPLICATION_XML_VALUE)
    public String contractNotity(HttpServletRequest request) {
        return wxPayService.contractNotify(request);
    }







    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }





}
